package ${packageName}.service.mapper;
<#if !!useProtobuf>
import com.boss.core.util.DateTimeUtil;
</#if>
import com.boss.core.base.service.mapper.BaseMapper;
import ${packageName}.domain.${classInfo.className};
import ${packageName}.dto.${classInfo.className}DTO;

import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

import org.springframework.stereotype.Service;

/**
 * ${classInfo.classComment}
 *
 * @author ${authorName} ${.now?string('yyyy-MM-dd')}
 */
@Service
public class ${classInfo.className}Mapper implements BaseMapper<${classInfo.className}, ${classInfo.className}DTO> {

    /**
     * convert ${classInfo.className}  to ${classInfo.className}DTO
     *
     * @param ${classInfo.className?uncap_first}
     * @return
     */
    @Override
    public ${classInfo.className}DTO toDTO(${classInfo.className} ${classInfo.className?uncap_first}) {
        BeanUtil.checkNotNull(${classInfo.className?uncap_first}, "${classInfo.className?uncap_first} must not be null");

        ${classInfo.className}DTO dto = new ${classInfo.className}DTO();
        BeanUtil.copyProperties(${classInfo.className?uncap_first},dto);
        return dto;
<#--
    <#list classInfo.fieldList as fieldItem >
        dto.set${fieldItem.fieldName?cap_first}(${classInfo.className?uncap_first}.get${fieldItem.fieldName?cap_first}());
    </#list>
-->

    }
    /**
     * convert ${classInfo.className}List  to ${classInfo.className}DTOList
     *
     * @param ${classInfo.className?uncap_first}List
     * @return
     */
    public List<${classInfo.className}DTO> toDTOList(List<${classInfo.className}> ${classInfo.className?uncap_first}List) {
        BeanUtil.checkNotNull(${classInfo.className?uncap_first}List, "${classInfo.className?uncap_first}List must not be null");
        return ${classInfo.className?uncap_first}List.stream()
        .filter(Objects::nonNull)
        .map(this::toDTO)
        .collect(Collectors.toList());
    }
    /**
     * convert ${classInfo.className}DTO to ${classInfo.className}
     *
     * @param dto
     * @return
     */
    @Override
    public ${classInfo.className} toEntity( ${classInfo.className}DTO dto) {
        BeanUtil.checkNotNull(dto, "${classInfo.className}DTO must not be null");

        ${classInfo.className} ${classInfo.className?uncap_first} = new ${classInfo.className}();
        BeanUtil.copyProperties(dto,${classInfo.className?uncap_first});
        return ${classInfo.className?uncap_first};
<#--
    <#list classInfo.fieldList as fieldItem >
        ${classInfo.className?uncap_first}.set${fieldItem.fieldName?cap_first}(dto.get${fieldItem.fieldName?cap_first}());
    </#list>
-->

    }

    /**
     * convert ${classInfo.className}DTOList  to ${classInfo.className}List
     *
     * @param ${classInfo.className?uncap_first}DTOList
     * @return
     */
    public List<${classInfo.className}> toEntityList(List<${classInfo.className}DTO> ${classInfo.className?uncap_first}DTOList) {
        BeanUtil.checkNotNull(${classInfo.className?uncap_first}DTOList, "${classInfo.className?uncap_first}DTOList must not be null");
        return ${classInfo.className?uncap_first}DTOList.stream()
        .filter(Objects::nonNull)
        .map(this::toEntity)
        .collect(Collectors.toList());
    }

    /**
     * Set Entity field value with DTO field which value is not null
     *
     * @param dto
     * @param ${classInfo.className?uncap_first}
     * @return
     */
    @Override
    public ${classInfo.className} toEntity(${classInfo.className}DTO dto, ${classInfo.className} ${classInfo.className?uncap_first}) {
        BeanUtil.checkNotNull(${classInfo.className?uncap_first}, "${classInfo.className?uncap_first} must not be null");
        BeanUtil.checkNotNull(dto, "dto must not be null");
        BeanUtil.copyProperties(dto,${classInfo.className?uncap_first}, true);
        return ${classInfo.className?uncap_first};
<#--
    <#list classInfo.fieldList as fieldItem >
        Optional.ofNullable(dto.get${fieldItem.fieldName?cap_first}()).ifPresent(${classInfo.className?uncap_first}::set${fieldItem.fieldName?cap_first});
    </#list>
-->

    }

<#if !!useProtobuf>
    /**
     * convert entity to protobuf
     * @param ${classInfo.className?uncap_first}
     * @return protobuf
     */
    public ${packageName}.proto.${classInfo.className} toProtobuf(${classInfo.className} ${classInfo.className?uncap_first}) {
        return ${packageName}.proto.${classInfo.className}.newBuilder()
<#list classInfo.fieldList as fieldItem >
<#if fieldItem.fieldClass == "Instant">
        .set${fieldItem.fieldName?cap_first}(DateTimeUtil.toTimestamp(${classInfo.className?uncap_first}.get${fieldItem.fieldName?cap_first}()))
<#else>
        .set${fieldItem.fieldName?cap_first}(${classInfo.className?uncap_first}.get${fieldItem.fieldName?cap_first}())
</#if>
</#list>
        .build();

    }

    /**
     * convert protobuf to entity
     * @param proto
     * @return entity
     */
    public ${classInfo.className} toEntity(${packageName}.proto.${classInfo.className} proto) {
        ${classInfo.className} ${classInfo.className?uncap_first} = new ${classInfo.className}();
<#list classInfo.fieldList as fieldItem >
<#if fieldItem.fieldClass == "Instant">
        ${classInfo.className?uncap_first}.set${fieldItem.fieldName?cap_first}(DateTimeUtil.toInstant(proto.get${fieldItem.fieldName?cap_first}()));
<#else>
        ${classInfo.className?uncap_first}.set${fieldItem.fieldName?cap_first}(proto.get${fieldItem.fieldName?cap_first}());
</#if>
</#list>
        return ${classInfo.className?uncap_first};
    }

</#if>

}
